const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "REJECTED";
class MyPromise {
  #PromiseState = PENDING;
  #PromiseResult = undefined;
  #handles = [];
  constructor(func) {
    const resolve = (value) => {
    this.#changeState(FULFILLED, value)
    };
    const reject = (reason) => {
      this.#changeState(REJECTED, reason) 
    };
    //执行器函数执行构造函数时立即执行
    func(resolve, reject);
  }
  //修改状态和结果
  #changeState(state, value) {
    if (this.#PromiseState !== PENDING) return;
      this.#PromiseResult = value;
      this.#PromiseState = state;
      this.#runHandlers()
  }
  #runHandlers() {
    if (this.#PromiseState === FULFILLED) {
      this.#handles.forEach(({ onFulfilled, newPromiseResolve, newPromiseReject }) =>this.#asyncHandle(onFulfilled, newPromiseResolve, newPromiseReject));
    }
    else {
      this.#handles.forEach(({ onRejected, newPromiseResolve, newPromiseReject }) => this.#asyncHandle(onRejected, newPromiseResolve, newPromiseReject));
    }
  } 
  //同步代码转位异步代码
  #asyncHandle(cb, newPromiseResolve, newPromiseReject) {
    queueMicrotask(() => {
      try {
        const returnValue = cb(this.#PromiseResult);
        if (returnValue instanceof MyPromise) {
          returnValue.then(newPromiseResolve, newPromiseReject);
        } else {
          newPromiseResolve(returnValue);
        }
      } catch (err) {
        newPromiseReject(err);
      }
    });
  }
  then(onFulfilled, onRejected) {
    if (typeof onFulfilled !== "function") onFulfilled = (value) => value;
    if (typeof onRejected !== "function") onRejected = (reason) => {throw reason};
      
    //实现.then链式调用
    return new MyPromise((resolve, reject) => {
      if (this.#PromiseState === FULFILLED) {
        this.#asyncHandle(onFulfilled, resolve, reject);
      } else if (this.#PromiseState === REJECTED) {
        this.#asyncHandle(onRejected, resolve, reject);
      } else {
        this.#handles.push({ onFulfilled, onRejected, newPromiseResolve: resolve, newPromiseReject: reject });
      }
    });
  }
}
